package com.johnny.cms.core;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;
import com.johnny.cms.core.dao.AuthorityDao;
import com.johnny.cms.core.domain.Conf;
import com.johnny.cms.core.domain.EmailConf;
import com.johnny.cms.core.domain.HomeConf;
import com.johnny.cms.core.domain.NotifyEvent;
import com.johnny.cms.core.domain.lg.Language;
import com.johnny.cms.core.domain.menu.Menu;
import com.johnny.cms.core.domain.menu.MenuGroup;
import com.johnny.cms.core.domain.security.Authority;
import com.johnny.cms.core.domain.security.Role;
import com.johnny.cms.core.domain.security.User;
import com.johnny.cms.core.domain.template.Template;
import com.johnny.cms.core.infrastructure.safe.MD5HashUtils;
import com.johnny.cms.core.listener.ISystemInitService;
import com.johnny.cms.core.manager.event.CmsApplicationListener;
import com.johnny.cms.core.manager.event.Init;
import com.johnny.cms.core.manager.trans.IContentManager;
import com.johnny.cms.core.manager.trans.ISystemConfigManager;
import com.johnny.cms.core.manager.trans.ISystemManager;
import com.johnny.cms.core.manager.trans.LanguageManager;
import com.johnny.cms.core.service.CmsBlogService;
import com.johnny.cms.core.service.CmsContentService;
import com.johnny.cms.core.service.CmsNOBService;
import com.johnny.cms.core.service.CmsSystemService;
import com.johnny.core.listener.PriorityMethod;

@Component("initDataService")
public class InitDataService implements CmsApplicationListener,
		ISystemInitService {
	@PriorityMethod(order = -99)
	public void onInit(Init init) {
		if (systemConfigManager.getConf() == null) {
			initAuth();
			initRole();
			initUser();
			initConf();
			initHomeConf();
			initEmailConf();
			initLanguage();
			initEvents();

		}
	}

	private void initLanguage() {
		newLanguage("English (US)", "en");
		newLanguage("Traditional Chinese", "zh_tw");
		newLanguage("Simplified Chinese", "zh_cn");
		newLanguage("Tamil", "ta");
		newLanguage("Hindi", "hi");
		newLanguage("Korean", "ko");
		newLanguage("Japanese", "ja");
		newLanguage("Bahasa Malay", "ms");
		newLanguage("Bahasa Indonesia", "id");
		newLanguage("Thai", "th");
		newLanguage("German", "de");
		newLanguage("French", "fr");
		newLanguage("Dutch", "dut");
		newLanguage("Russian", "ru");
		newLanguage("Spanish", "es");
		newLanguage("Italian", "it");
		newLanguage("Arabic", "ara");
	}

	private void newLanguage(String name, String lg) {
		Language language = new Language();
		language.setLg(lg);
		language.setLanguage(name);
		languageManager.saveLanguage(language);
	}

	@Autowired
	private AuthorityDao authorityDao;
	@Resource(name = "systemManager")
	private ISystemManager accountManager;
	@Resource(name = "systemConfigManager")
	private ISystemConfigManager systemConfigManager;
	@Resource(name = "contentManager")
	private IContentManager contentManager;
	@Autowired
	private LanguageManager languageManager;

	private List<String> auths = Lists.newArrayList(

	"resource:list", "email-conf:edit", "home-conf:edit",
			"security-resource:delete", "photo-resource:list",
			"resource:upload", "photo-resource:upload", "resource:download",
			"photo-resource:download", "security-resource:list",
			"security-resource:upload", "photo-resource:delete",
			"security-resource:download", "channel:list", "resource:delete",
			"channel:create", "channel:edit", "channel:delete",
			"template:list", "template:create", "template:edit",
			"template:delete", "conf:edit", "notify-event:list",
			"notify-event:edit", "parameter:list", "parameter:edit",
			"parameter-group:list", "parameter-group:edit", "post:create",
			"post:edit", "post:list", "post-comment:list", "post-comment:edit",
			"album:list", "album:edit", "nbo-enquiry:list", "nbo-contact:list",
			"article:list", "article:create", "article:edit", "language:list",
			"menu-group:create", "menu-group:edit", "menu-group:list",
			"menu:create", "menu:edit", "menu:list", "post-catetory:list"

	);

	public void initAuth() {

		for (String s : this.auths) {
			addNewAuth(s);
		}
	}

	private void addNewAuth(String auth) {
		Authority authority = new Authority();
		authority.setName(auth);
		authority.setDescriptoin(auth);
		authorityDao.save(authority);
	}

	public void initRole() {
		Role role = new Role();
		role.setName("admin");

		role.setAuthorityList(authorityDao.getAll());
		accountManager.saveRole(role);
	}

	public void initUser() {
		User user = new User();
		user.setLoginName("admin");
		user.setEmail("johnnywalee@gmail.com");
		user.setPassword(MD5HashUtils.asMD5("admin135", user.getLoginName()));
		user.setRoleList(accountManager.getAllRole());
		user.setActived(Boolean.TRUE);
		user.setName("admin");
		accountManager.saveUser(user);

		user = new User();
		user.setLoginName("johnny");
		user.setEmail("johnnywalee@gmail.com");
		user.setPassword(MD5HashUtils.asMD5("admin135", user.getLoginName()));
		user.setRoleList(accountManager.getAllRole());
		user.setActived(Boolean.TRUE);
		user.setName("johnny");
		accountManager.saveUser(user);

	}

	public void initConf() {
		Conf conf = new Conf()
				.setTemplatePath("resources/front/template")
				.setResourcePath("resources")
				.setSecurityResourcePath("WEB-INF")
				.setAttachmentPath("attachments")
				.setPhotoPath("resources/photos")
				.setAllowedPhotoTypes("jpg,jpeg,bmp,gif,png,ico")
				.setAllowedSecurityResourceTypes("jsp,ftl,html,htm,txt")
				.setAllowedResourceTypes(
						"jpg,jpeg,bmp,gif,png,ico;txt,doc,docx,ppt,xls,pdf;js,css,xml;zip,rar;")
				.setMaxResourceSize(5 * 1024 * 1024);
		conf.setHostName("119.73.251.115:7070/");
		conf.setActiveURL("user/activity/UUID/");
		conf.setTemplateFileStore("WEB-INF/cms-template");
		conf.setAlbumPath("resources/album");
		systemConfigManager.saveConf(conf);
	}

	public void initHomeConf() {
		HomeConf homeConf = new HomeConf();
		homeConf.setId(1l);
		homeConf.setMetaDescription("home");
		homeConf.setMetaKeywords("keywork");
		homeConf.setMetaTitle("title");
		homeConf.setTitle("Title");
		contentManager.saveHomeConf(homeConf);
	}

	public void initEmailConf() {
		EmailConf emailConf = new EmailConf();
		emailConf.setId(1l);
		emailConf.setSmtpServer("smtp.gmail.com");
		emailConf.setPort(465);
		emailConf.setUsername("johnny4test@gmail.com");
		emailConf.setPassword("abcd1234abcd12"); // nobabcd1234
		emailConf.setSender("johnny4test@gmail.com");
		emailConf.setReceivers("nob2014@gmail.com");
		emailConf.setStarttls(true);
		emailConf.setAuth(true);
		emailConf.setSslEnable(true);
		systemConfigManager.saveEmailConf(emailConf);
	}

	public void initEvents() {
		Set<String> notifyEvents = new HashSet<String>();
		notifyEvents.add("modify");
		notifyEvents.add("create");
		notifyEvents.add("delete");
		Set<String> events = new HashSet<String>();
		events.addAll(getEvents(notifyEvents, CmsSystemService.class));
		events.addAll(getEvents(notifyEvents, CmsContentService.class));
		events.addAll(getEvents(notifyEvents, CmsBlogService.class));
		events.addAll(getEvents(notifyEvents, CmsNOBService.class));

		for (String event : events) {
			NotifyEvent notifyEvent = new NotifyEvent();
			notifyEvent.setEmail(false);
			notifyEvent.setLog(true);
			notifyEvent.setSms(false);
			notifyEvent.setName(event);

			List<Integer> indexs = new ArrayList<Integer>();
			for (int i = 0; i < event.length(); i++) {
				char c = event.charAt(i);
				if (Character.isUpperCase(c)) {
					indexs.add(i);
				}
			}
			String viewName = event;
			for (int i = indexs.size() - 1; i >= 0; i--) {
				Integer index = indexs.get(i);
				viewName = viewName.substring(0, index) + " "
						+ viewName.substring(index);
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(Character.toUpperCase(viewName.charAt(0)));
			stringBuilder.append(viewName.substring(1));
			notifyEvent.setViewName(stringBuilder.toString());
			systemConfigManager.saveNotifyEvent(notifyEvent);

		}

	}

	public Set<String> getEvents(Set<String> key, Class clazz) {

		Set<String> result = new HashSet<String>();
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			for (String s : key) {
				if (method.getName().startsWith(s)) {
					result.add(method.getName());
					break;
				}

			}
		}
		return result;
	}

	@Override
	public void initTemplates(Conf conf) {
		String root = conf.getRootPath();
		File file = new File(root);
		File source = new File(file, "install");
		File desc = new File(file, "WEB-INF/cms-template");

		try {
			FileUtils.copyDirectory(source, desc);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		initMenu();
		initSecond();
		template();
	}

	public void initMenu() {
		MenuGroup menuGroup = new MenuGroup();
		menuGroup.setName("header");
		menuGroup.setDescription("For title");
		contentManager.saveMenuGroup(menuGroup);

		Menu whoWeAre = getMenu(menuGroup, "Who we are", 0, "index", null);
		getMenu(menuGroup, "Our Philosophy", 0, "who-philosophy", whoWeAre);
		getMenu(menuGroup, "NBO Team", 1, "who-team", whoWeAre);

		Menu ourSolutions = getMenu(menuGroup, "Our Philosophy", 1,
				"solutions", null);
		getMenu(menuGroup, "Overview", 0, "solutions-solutions", ourSolutions);
		getMenu(menuGroup, "Consulting", 1, "solutions-consulting",
				ourSolutions);
		getMenu(menuGroup, "Leadership", 2, "solutions-leadership",
				ourSolutions);
		getMenu(menuGroup, "Management Effectiveness", 3,
				"solutions-management", ourSolutions);
		getMenu(menuGroup, "Team Development", 4, "solutions-team",
				ourSolutions);
		getMenu(menuGroup, "Communication Effectiveness", 5,
				"solutions-communication", ourSolutions);
		getMenu(menuGroup, "360 Feedback System", 6, "solutions-360feedback",
				ourSolutions);
		getMenu(menuGroup, "What Bosses Want", 7, "solutions-boss",
				ourSolutions);

		Menu clientSuccesses = getMenu(menuGroup, "Client Successes", 2,
				"client", null);
		getMenu(menuGroup, "Clients", 0, "client-list", clientSuccesses);
		getMenu(menuGroup, "Case Studies", 1, "client-case", clientSuccesses);

		Menu partner = getMenu(menuGroup, "Partners", 3, "partner", null);

		getMenu(menuGroup, "Find Our Partners", 0, "partner-map", partner);
		getMenu(menuGroup, "Join Our Alliance", 1, "join", partner);

		Menu resource = getMenu(menuGroup, "Resources", 4, "resource", null);

		getMenu(menuGroup, "Brochures", 0, "resource-brochures", resource);
		getMenu(menuGroup, "Articles", 1, "resource-articles", resource);
		getMenu(menuGroup, "Whitepapers", 2, "resource-whitepapers", resource);
		getMenu(menuGroup, "Videos", 3, "resource-videos", resource);

	}

	public void initSecond() {
		MenuGroup menuGroup = new MenuGroup();
		menuGroup.setName("second");
		menuGroup.setDescription("second");
		contentManager.saveMenuGroup(menuGroup);

		getMenu(menuGroup, "Blog", 0, "blog", null);
		getMenu(menuGroup, "Gallery", 0, "gallery", null);
		getMenu(menuGroup, "Contact Us", 0, "contact", null);

	}

	public void template() {
		disableInline("nbo/blog-article");
		disableInline("nbo/blog");
		disableInline("master");
		disableInline("nbo/search");
		disableInline("nbo/download");
		disableInline("nbo/gallery-album43a0");
		disableInline("nbo/gallery");
		disableInline("nbo/resource-article");

	}

	public void disableInline(String name) {
		Template template = contentManager.getTemplateByName(name);
		if (template == null) {
			System.out.println("fail to get template by name " + name);
		} else {
			template.setInlineEdit(false);
			contentManager.saveTemplateNoFileSave(template);
		}
	}

	private Menu getMenu(MenuGroup menuGroup, String title, int order,
			String channel, Menu father) {

		Menu menu = new Menu();
		menu.setMenuGroup(menuGroup);
		menu.setName(title);
		menu.setTitle(title);
		menu.setRankOrder(order);
		menu.setChannel(contentManager.getChannelByPath(channel));
		menu.setFather(father);
		contentManager.saveMenu(menu);
		return menu;
	}

}
